Skip to main content
Glama

CJ-MCP

by PoivronMax
Dependency系统对比分析.md13.5 kB
# ArkTS vs 仓颉:Dependency 系统对比分析 > 目的:分析 ArkTS 的 `Dependency`、`StateToScopes`、`ScopeToStates` 与仓颉的 `Dependency`、`Dependencies` 在功能上的差异,并说明在不修改仓颉现有实现的情况下,需要补充哪些功能。 参考代码: - ArkTS: `/home/gloria/Cangjie/arkui_ace_engine/frameworks/bridge/arkts_frontend/koala_projects/incremental/runtime/src/states/Dependency.ts` - 仓颉: `/home/gloria/Cangjie/incremental_runtime/runtime/src/core/Dependency.cj` --- ## 目录 1. [ArkTS 实现的功能](#1-arkts-实现的功能) - [Dependency 接口](#11-dependency-接口) - [StateToScopes 类](#12-statetoscopes-类) - [ScopeToStates 类](#13-scopetostates-类) - [双向依赖关系](#14-双向依赖关系) 2. [仓颉实现的功能](#2-仓颉实现的功能) - [Dependency 抽象类](#21-dependency-抽象类) - [Dependencies 类](#22-dependencies-类) 3. [功能对比与 Gap 分析](#3-功能对比与-gap-分析) - [架构差异](#31-架构差异) - [关键功能 Gap](#32-关键功能-gap) 4. [不修改现有实现的情况下,需要补充的功能](#4-不修改现有实现的情况下需要补充的功能) - [必须补充:条件失效(invalidateIf)](#41-必须补充条件失效invalidateif) - [可选补充:Scope 侧依赖查询(ScopeToStates 等价物)](#42-可选补充scope-侧依赖查询scopetostates-等价物) - [可选补充:双向链接辅助类](#43-可选补充双向链接辅助类) 5. [最小补充方案(推荐)](#5-最小补充方案推荐) 6. [完整补充方案(如果允许修改现有实现)](#6-完整补充方案如果允许修改现有实现) 7. [总结](#7-总结) --- ## 1. ArkTS 实现的功能 ### 1.1 Dependency 接口 ```typescript export interface Dependency { readonly states: ScopeToStates | undefined } ``` **功能**:表示一个可被通知变化的观察者,通过 `states` 属性访问其依赖的状态集合。 **实现者**:`ManagedScope` 实现了 `Dependency` 接口,通过 `states` 属性暴露其依赖的状态。 --- ### 1.2 StateToScopes 类 ```typescript export class StateToScopes implements Unique { private readonly dependencies = new UniqueSet<ScopeToStates> add(dependency: ScopeToStates): void remove(dependency: ScopeToStates): void clear(): undefined invalidate(): void invalidateIf(predicate: (element: ScopeToStates) => boolean): void register(dependency?: Dependency): void } ``` **功能**: - **存储**:State → 多个 Scope 的映射(通过 `UniqueSet<ScopeToStates>`) - **双向链接**:`register()` 时,`this.add(that)` 和 `that.add(this)`,建立双向依赖 - **失效**:`invalidate()` 失效所有依赖的 Scope;`invalidateIf()` 条件失效(用于属性级追踪) **使用位置**:`StateImpl.dependencies: StateToScopes`,存储依赖该 State 的所有 Scope。 --- ### 1.3 ScopeToStates 类 ```typescript export class ScopeToStates implements Unique { private readonly dependencies = new UniqueMap<StateToScopes, Boolean> readonly invalidate: () => void add(dependency: StateToScopes): void remove(dependency: StateToScopes): void clear(): undefined reset(): void // 清理未使用的依赖 } ``` **功能**: - **存储**:Scope → 多个 State 的映射(通过 `UniqueMap<StateToScopes, Boolean>`) - **失效回调**:构造时传入 `invalidate()` 回调,指向 Scope 的失效方法 - **清理**:`reset()` 清理未使用的依赖(基于 marker 机制) **使用位置**:`ScopeImpl._states: ScopeToStates`,存储该 Scope 依赖的所有 State。 --- ### 1.4 双向依赖关系 ``` State.dependencies (StateToScopes) ↓ 包含多个 ScopeToStates (在各个Scope._states中) ↓ 包含多个 State.dependencies (回到StateToScopes) ``` **建立流程**: ```typescript // StateImpl.onAccess() onAccess(propertyName?: string): void { const dependency = this.manager?.dependency // 获取当前Scope this.dependencies?.register(dependency) // 双向注册 } // StateToScopes.register() register(dependency?: Dependency): void { const that = dependency?.states // 获取ScopeToStates if (that) { this.add(that) // State记录Scope that.add(this) // Scope记录State } } ``` --- ## 2. 仓颉实现的功能 ### 2.1 Dependency 抽象类 ```cj public abstract class Dependency <: UniqueObject & Equatable<Dependency> { public func invalidate(): Unit } ``` **功能**:表示一个可被通知失效的观察者,通过 `invalidate()` 方法被通知失效。 **实现者**:`ManagedScope` 实现了 `Dependency`,通过 `invalidate()` 方法实现失效传播。 --- ### 2.2 Dependencies 类 ```cj public class Dependencies { private var dependencies = None<HashSet<Dependency>> private var latest = None<Dependency> func register(dependency: ?Dependency): Unit public func onUpdate(invalidate: Bool): Unit } ``` **功能**: - **存储**:存储 `HashSet<Dependency>`(即 Scope 集合),或单个 `latest` - **注册**:`register()` 将 Dependency(即 Scope)添加到集合 - **更新**:`onUpdate(invalidate)` 根据 `invalidate` 标志决定是否失效所有依赖 **使用位置**: - `StateImpl.dependencies: ?Dependencies`,存储依赖该 State 的所有 Scope - `ParameterImpl.dependencies: ?Dependencies`,存储依赖该参数的所有 Scope - `ScopeImpl.dependencies: ?Dependencies`,存储该 Scope 依赖的其他 Dependency --- ## 3. 功能对比与 Gap 分析 ### 3.1 架构差异 | 特性 | ArkTS | 仓颉 | |------|-------|------| | **依赖方向** | 双向链接(State ↔ Scope) | 单向集合(State → Scope) | | **存储结构** | `StateToScopes` ↔ `ScopeToStates` | `Dependencies`(仅存储 Scope) | | **双向注册** | `register()` 自动双向链接 | 仅单向注册(State → Scope) | | **Scope 侧依赖** | `Scope._states: ScopeToStates` | `Scope.dependencies: ?Dependencies`(存储其他 Dependency) | --- ### 3.2 关键功能 Gap #### Gap 1: 双向链接缺失 **ArkTS**: - `StateToScopes.register()` 会同时调用 `this.add(that)` 和 `that.add(this)` - Scope 通过 `_states: ScopeToStates` 可以查询自己依赖了哪些 State **仓颉**: - `Dependencies.register()` 只做单向注册(State → Scope) - Scope 没有直接查询"依赖了哪些 State"的能力 **影响**: - Scope 无法主动清理不再使用的依赖(ArkTS 的 `ScopeToStates.reset()`) - 无法实现"从 Scope 出发查询依赖"的功能 --- #### Gap 2: 条件失效(invalidateIf)缺失 **ArkTS**: ```typescript StateToScopes.invalidateIf(predicate: (element: ScopeToStates) => boolean): void { this.dependencies.forEach((dependency: ScopeToStates) => { if (predicate(dependency)) dependency.invalidate() }) } ``` **仓颉**: - `Dependencies.onUpdate()` 只有 `invalidate: Bool` 标志,无法条件失效 **影响**: - **无法实现属性级失效**:当对象属性修改时,无法只失效访问了该属性的 Scope - 必须整体失效,导致过度失效 **使用场景**(ArkTS): ```typescript // StateImpl.updateStateSnapshot() if (modifiedTrackedScopes) { dependencies.invalidateIf((dependency: ScopeToStates): boolean => { return modifiedTrackedScopes?.has(dependency) == true }) } else { dependencies.invalidate() } ``` --- #### Gap 3: Scope 侧依赖查询缺失 **ArkTS**: - `Scope._states: ScopeToStates` 可以查询 Scope 依赖了哪些 State - `ScopeToStates.reset()` 可以清理未使用的依赖 **仓颉**: - `Scope.dependencies: ?Dependencies` 存储的是其他 Dependency(如子 Scope),不是依赖的 State - 无法查询 Scope 依赖了哪些 State **影响**: - 无法实现依赖清理(reset)机制 - 无法实现"从 Scope 出发查询依赖"的功能 --- #### Gap 4: 依赖清理机制缺失 **ArkTS**: ```typescript ScopeToStates.reset(): void { const current = this.marker this.marker = !current this.dependencies.deleteIf((dependency: StateToScopes, marker: Boolean) => { if (current == marker) return false dependency.remove(this) return true }) } ``` **仓颉**: - `Dependencies` 没有 `reset()` 机制 - 依赖一旦注册,除非 Scope 销毁,否则不会自动清理 **影响**: - 依赖可能累积,无法及时清理不再使用的依赖 - 可能导致内存泄漏或性能问题 --- ## 4. 不修改现有实现的情况下,需要补充的功能 ### 4.1 必须补充:条件失效(invalidateIf) **位置**:在 `Dependencies` 类中添加 **实现**: ```cj public func invalidateIf(predicate: (Dependency) -> Bool): Unit { if (let Some(dependencies) <- this.dependencies) { for (dependency in dependencies) { if (predicate(dependency)) { dependency.invalidate() } } } else if (let Some(latest) <- this.latest) { if (predicate(latest)) { latest.invalidate() } } } ``` **用途**: - 支持属性级失效(结合 `TrackedScopes`) - 支持细粒度失效控制 **影响**:这是实现属性级更新的**关键前提**。 --- ### 4.2 可选补充:Scope 侧依赖查询(ScopeToStates 等价物) **位置**:在 `ManagedScope` 或 `ScopeImpl` 中添加新字段 **实现**: ```cj // 在 ManagedScope 中添加 private var states = None<ScopeStates> class ScopeStates { private var dependencies = None<HashSet<StateToScopes>> func add(state: StateToScopes): Unit func remove(state: StateToScopes): Unit func reset(): Unit // 清理未使用的依赖 } ``` **注意**:这需要修改 `ManagedScope` 结构,可能与"不修改现有实现"冲突。 **替代方案**:通过 `Dependencies` 的扩展方法实现,不修改 `ManagedScope`。 --- ### 4.3 可选补充:双向链接辅助类 **位置**:新增 `StateToScopes` 和 `ScopeToStates` 等价类 **实现**: ```cj // 新增 StateToScopes 类 public class StateToScopes { private var dependencies = None<HashSet<ScopeStates>> func register(dependency: ?Dependency): Unit { // 双向注册逻辑 } func invalidateIf(predicate: (ScopeStates) -> Bool): Unit { // 条件失效 } } // 新增 ScopeToStates 类 public class ScopeToStates { private var dependencies = None<HashSet<StateToScopes>> let invalidate: () -> Unit func add(state: StateToScopes): Unit func reset(): Unit } ``` **注意**:这需要修改 `StateImpl` 和 `ScopeImpl` 的字段类型,可能与"不修改现有实现"冲突。 --- ## 5. 最小补充方案(推荐) ### 方案:仅补充 `invalidateIf` 方法 **理由**: 1. **最小改动**:只需在 `Dependencies` 类中添加一个方法 2. **关键功能**:这是实现属性级失效的**唯一前提** 3. **向后兼容**:不影响现有代码 **实现**: ```cj // 在 Dependencies 类中添加 public func invalidateIf(predicate: (Dependency) -> Bool): Unit { if (let Some(dependencies) <- this.dependencies) { for (dependency in dependencies) { if (predicate(dependency)) { dependency.invalidate() } } } else if (let Some(latest) <- this.latest) { if (predicate(latest)) { latest.invalidate() } } } ``` **使用场景**: - 在 `StateImpl.updateStateSnapshot()` 中,结合 `TrackedScopes` 实现属性级失效 - 在 `Dependencies.onUpdate()` 中,当需要条件失效时调用 --- ## 6. 完整补充方案(如果允许修改现有实现) 如果需要完整实现 ArkTS 的功能,需要: 1. **修改 `StateImpl`**: - 将 `dependencies: ?Dependencies` 改为 `dependencies: ?StateToScopes` - `StateToScopes` 类实现双向链接 2. **修改 `ScopeImpl`**: - 添加 `_states: ?ScopeToStates` 字段 - `ScopeToStates` 类存储 Scope 依赖的 State 3. **修改注册逻辑**: - `StateToScopes.register()` 实现双向注册 - `ScopeToStates.add()` 实现双向添加 4. **添加清理机制**: - `ScopeToStates.reset()` 清理未使用的依赖 --- ## 7. 总结 ### 功能对比表 | 功能 | ArkTS | 仓颉 | Gap | |------|-------|------|-----| | **双向链接** | ✅ State ↔ Scope | ❌ 仅 State → Scope | 有 | | **条件失效** | ✅ `invalidateIf()` | ❌ 缺失 | 有 | | **Scope 侧查询** | ✅ `Scope._states` | ❌ 缺失 | 有 | | **依赖清理** | ✅ `reset()` | ❌ 缺失 | 有 | | **基础失效** | ✅ `invalidate()` | ✅ `onUpdate(true)` | 无 | ### 最小补充建议 **必须补充**:`Dependencies.invalidateIf()` 方法 - 理由:实现属性级失效的**关键前提** - 影响:支持细粒度失效,避免过度失效 - 改动:最小,仅添加一个方法 **可选补充**:Scope 侧依赖查询(如果允许修改 `ManagedScope`) - 理由:实现依赖清理和从 Scope 出发的查询 - 影响:提升依赖管理能力,避免依赖累积 - 改动:需要修改 `ManagedScope` 结构 --- **关键结论**: - 仓颉的 `Dependencies` 类已经实现了基础依赖管理功能 - **主要缺失**是 `invalidateIf()` 方法,这是实现属性级更新的**关键前提** - 双向链接和依赖清理是可选的增强功能,但 `invalidateIf()` 是必须的

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PoivronMax/idlize-cj-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server